package com.zmn.oms.business.impl.conf.attachment;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.aliyun.openservices.shade.org.apache.commons.lang3.math.NumberUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.common.query.ChannelQuery;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.plat.engine.common.constant.DubboConsts;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.categ.CategServDRO;
import com.zmn.base.product.common.dto.product.ProductBaseQuery;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.base.product.common.dto.product.erp.ProductBusinessLineDRO;
import com.zmn.base.product.common.query.categ.ForeignCategServQuery;
import com.zmn.base.product.common.query.product.erp.ProductBusinessLineQuery;
import com.zmn.base.product.dubbo.interfaces.categ.serv.CategServListRemoteService;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductBusinessLineForeignListRemoteService;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductForeignListRemoteService;
import com.zmn.common.dto2.AMISListData;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.business.interfaces.conf.attachment.ConfOrderAttachmentBService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dio.conf.attachment.ConfOrderAttachmentDIO;
import com.zmn.oms.model.entity.conf.attachment.ConfOrderAttachment;
import com.zmn.oms.model.entity.conf.attachment.ConfOrderAttachmentCategory;
import com.zmn.oms.model.entity.conf.attachment.ConfOrderAttachmentCategoryQuery;
import com.zmn.oms.model.entity.conf.attachment.ConfOrderAttachmentQuery;
import com.zmn.oms.model.entity.conf.attachment.channel.ConfOrderAttachmentChannel;
import com.zmn.oms.model.entity.conf.attachment.channel.ConfOrderAttachmentChannelDIO;
import com.zmn.oms.model.entity.conf.attachment.channel.ConfOrderAttachmentChannelDRO;
import com.zmn.oms.model.entity.conf.attachment.city.ConfOrderAttachmentCity;
import com.zmn.oms.model.entity.conf.attachment.city.ConfOrderAttachmentCityDRO;
import com.zmn.oms.model.entity.conf.attachment.city.ConfOrderAttachmentCityQuery;
import com.zmn.oms.model.entity.conf.attachment.product.ConfOrderAttachmentProduct;
import com.zmn.oms.model.entity.conf.attachment.product.ConfOrderAttachmentProductQuery;
import com.zmn.oms.model.entity.orderattachment.OrderAttachmentQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.query.conf.attachment.channel.ConfOrderAttachmentChannelQuery;
import com.zmn.oms.model.vo.conf.attachment.ConfOrderAttachmentPictureVO;
import com.zmn.oms.model.vo.conf.attachment.ConfOrderAttachmentVO;
import com.zmn.oms.model.vo.conf.attachment.ConfOrderChannelQuery;
import com.zmn.oms.model.vo.conf.attachment.ServerClassDataBO;
import com.zmn.oms.services.interfaces.conf.attachment.*;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 类描述：订单标签
 *
 * @author liuying
 * @date 2021/05/06 17:03
 */
@Slf4j
@Service
public class ConfOrderAttachmentBServiceImpl implements ConfOrderAttachmentBService {

    @Autowired
    private ConfOrderAttachmentService confOrderAttachmentService;
    @Resource
    private ConfOrderAttachmentCategoryService confOrderAttachmentCategoryService;
    @Resource
    private OrderWorkService orderWorkService;
    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false, timeout = 10000)
    protected ProductBusinessLineForeignListRemoteService productBusinessLineForeignListRemoteService;
    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false, timeout = 10000)
    private ChannelListRemoteService channelListRemoteService;
    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    protected CategServListRemoteService categServListRemoteService;
    @Resource
    private ConfOrderAttachmentChannelService confOrderAttachmentChannelService;
    @Resource
    private ConfOrderAttachmentCityService confOrderAttachmentCityService;
    @Resource
    private ConfOrderAttachmentProductService confOrderAttachmentProductService;
    @Resource
    private ProductForeignListRemoteService productForeignListRemoteService;
    @Resource
    private ConfOrderAttachmentStandardService confOrderAttachmentStandardService;



    private static String TAG = "照片配置";

    /**
     * 获取【照片配置】集合
     *
     * @param orderAttachmentQuery
     * @return
     */
    @Override
    public List<ConfOrderAttachment> listConfigOrderPictureAttachmentByQuery(OrderAttachmentQuery orderAttachmentQuery) {
        try {
            // 组装查询对象
            ConfOrderAttachmentQuery confOrderAttachmentQuery = ConfOrderAttachmentQuery.builder()
                    .bizType(orderAttachmentQuery.getBizType())
                    .productId(orderAttachmentQuery.getProductId())
                    .cityId(orderAttachmentQuery.getCityId())
                    .channelId(orderAttachmentQuery.getChannelId())
                    .servCategIdList(Lists.newArrayList(String.valueOf(orderAttachmentQuery.getServCategId())))
                    .type(OrderAttachmentCategoryTypeEnum.PICTURE.getCode())
                    .orderDetailShow(orderAttachmentQuery.getOrderDetailShow())
                    .build();

            // 如果有【附件类型】按照附件类型
            if (Objects.nonNull(orderAttachmentQuery.getType())) {
                confOrderAttachmentQuery.setCategId(orderAttachmentQuery.getType());
            }

            // 获取照片配置
            log.info("工单号：[{}]，开始查询【“照片” 配置】集合", orderAttachmentQuery.getOrderId());
            List<ConfOrderAttachment> pictureConfigList = this.listConfigOrderAttachmentPictureByQuery(confOrderAttachmentQuery);

            // 获取需要的订单附件类型
            List<Integer> categIds = orderAttachmentQuery.getCategIds();
            if (CollectionUtil.isNotNullOrEmpty(categIds)){
                pictureConfigList = pictureConfigList.stream().filter(pictureConfig-> categIds.contains(pictureConfig.getCategId()))
                        .collect(Collectors.toList());
            }


            // 按 附件类型 分组
            Map<Integer, ConfOrderAttachment> pictureConfigMap = pictureConfigList.stream()
                    .collect(Collectors.toMap(ConfOrderAttachment::getCategId, (conf -> conf), (oldVal, newVal) -> oldVal));

            // 查询orderWork
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderAttachmentQuery.getOrderId(), orderAttachmentQuery.getWorkId());

            // 过滤不满足条件的【照片配置】
            this.filterPictureConfigBySpecialRules(orderWork, pictureConfigMap);

            List<ConfOrderAttachment> confOrderAttachmentList = Lists.newArrayList(pictureConfigMap.values());
            log.debug("工单号：[{}]，查询【“照片配置”集合】 出参：{}", orderAttachmentQuery.getOrderId(), confOrderAttachmentList);

            confOrderAttachmentList = confOrderAttachmentList.stream().sorted(Comparator.comparing(ConfOrderAttachment::getSort)).collect(Collectors.toList());
            return confOrderAttachmentList;
        } catch (Exception ex) {
            log.error("工单号：[{}]，查询【“照片配置”集合】 异常：[{}]", orderAttachmentQuery.getOrderId(), ex);
            return Lists.newArrayList();
        }
    }

    /**
     * 根据查询条件查出对应的【视频附件配置】
     *
     * @param orderAttachmentQuery 查询配置
     * @return
     */
    @Override
    public List<ConfOrderAttachment> listConfigOrderVideoAttachmentByQuery(OrderAttachmentQuery orderAttachmentQuery) {
        try {
            ConfOrderAttachmentQuery confOrderAttachmentQuery = ConfOrderAttachmentQuery.builder()
                    .bizType(orderAttachmentQuery.getBizType())
                    .channelIdList(Lists.newArrayList(String.valueOf(orderAttachmentQuery.getChannelId())))
                    .servCategIdList(Lists.newArrayList(String.valueOf(orderAttachmentQuery.getServCategId())))
                    .type(OrderAttachmentCategoryTypeEnum.VIDEO.getCode())
                    .build();

            // 获取视频配置
            return this.listConfigOrderAttachmentByQuery(confOrderAttachmentQuery);

        } catch (Exception ex) {
            log.error("工单号：[{}]，查询【“视频配置” 集合】 异常：[{}]", orderAttachmentQuery.getOrderId(), ex);
            return Lists.newArrayList();
        }
    }


    /**
     * 查询出对应的【照片】附件配置集合
     *
     * @param confOrderAttachmentQuery
     * @return
     */
    private List<ConfOrderAttachment> listConfigOrderAttachmentPictureByQuery(ConfOrderAttachmentQuery confOrderAttachmentQuery) {
        // 查询渠道
        List<ConfOrderAttachmentChannel> channels = confOrderAttachmentChannelService.listByQuery(ConfOrderAttachmentChannelQuery.builder().channelId(confOrderAttachmentQuery.getChannelId()).excludeType(ConfOrderAttachmentChannelTypeConsts.TYPE_USE).build());
        List<ConfOrderAttachmentChannel> excludeChannels = confOrderAttachmentChannelService.listByQuery(ConfOrderAttachmentChannelQuery.builder().excludeType(ConfOrderAttachmentChannelTypeConsts.TYPE_EXCLUDE).build());
        List<Integer> useChannelAttachmentIds = channels.stream().map(ConfOrderAttachmentChannel::getAttachmentId).collect(Collectors.toList());
        List<Integer> excludeChannelAttachmentIds = excludeChannels.stream()
                .filter(channel -> {
                    if (channel.getChannelId().equals(confOrderAttachmentQuery.getChannelId())){
                        return false;
                    }
                    return true;
                }).map(ConfOrderAttachmentChannel::getAttachmentId).collect(Collectors.toList());
        useChannelAttachmentIds.addAll(excludeChannelAttachmentIds);
        useChannelAttachmentIds = useChannelAttachmentIds.stream().distinct().collect(Collectors.toList());
        // 查询城市
        List<ConfOrderAttachmentCity> cities = confOrderAttachmentCityService.listByQuery(ConfOrderAttachmentCityQuery.builder().cityId(confOrderAttachmentQuery.getCityId()).build());
        List<Integer> cityAttachmentIds = cities.stream().map(ConfOrderAttachmentCity::getAttachmentId)
                .distinct().collect(Collectors.toList());
        // 查询产品
        List<ConfOrderAttachmentProduct> products = confOrderAttachmentProductService.listByQuery(ConfOrderAttachmentProductQuery.builder().productId(confOrderAttachmentQuery.getProductId()).build());
        List<Integer> productAttachmentIds = products.stream().map(ConfOrderAttachmentProduct::getAttachmentId)
                .distinct().collect(Collectors.toList());
        confOrderAttachmentQuery.setChannelAttachmentIds(useChannelAttachmentIds);
        confOrderAttachmentQuery.setProductAttachmentIds(productAttachmentIds);
        confOrderAttachmentQuery.setCityAttachmentIds(cityAttachmentIds);

        // 查询所有满足条件的附件配置Id集合
        log.debug("查询数据库中的附件配置，入参：[{}]", confOrderAttachmentQuery);
        List<ConfOrderAttachment> dbConfOrderAttachmentList = confOrderAttachmentService.listPictureByQuery(confOrderAttachmentQuery);
        log.debug("查询数据库中的附件配置，出参：{}", dbConfOrderAttachmentList);

        if (CollectionUtils.isEmpty(dbConfOrderAttachmentList)) {
            log.info("未查询出符合条件的附件配置，入参：[{}]", confOrderAttachmentQuery);
            return Lists.newArrayList();
        }
        return dbConfOrderAttachmentList;
    }

    /**
     * 查询出对应的【照片/视频】附件配置集合
     *
     * @param confOrderAttachmentQuery
     * @return
     */
    private List<ConfOrderAttachment> listConfigOrderAttachmentByQuery(ConfOrderAttachmentQuery confOrderAttachmentQuery) {
        log.debug("查询数据库中的附件配置，入参：[{}]", confOrderAttachmentQuery);
        List<ConfOrderAttachment> dbConfOrderAttachmentList = confOrderAttachmentService.listByQueryAndChannelIdsOrServCategIds(confOrderAttachmentQuery);
        log.debug("查询数据库中的附件配置，出参：{}", dbConfOrderAttachmentList);

        if (CollectionUtils.isEmpty(dbConfOrderAttachmentList)) {
            log.info("未查询出符合条件的附件配置，入参：[{}]", confOrderAttachmentQuery);
            return Lists.newArrayList();
        }

        String channelId = confOrderAttachmentQuery.getChannelIdList().get(0);

        // 筛选出哪些配置可以应用到本渠道上，筛选条件：全应用渠道、部分应用渠道、部分排除渠道；
        List<ConfOrderAttachment> attachmentConfigFilterList = dbConfOrderAttachmentList.stream().filter(item ->
                // 全应用渠道
                (StringUtil.isBlank(item.getChannelIds()) && StringUtil.isBlank(item.getExcludeChannelIds()))

                        // 若【订单】的渠道，匹配上了“当前附件配置”的【应用渠道】，则“应用”这个【附件配置】
                        || Lists.newArrayList(item.getChannelIds().split(",")).contains(channelId)

                        // 若【订单】的渠道，匹配上了“当前附件配置”的【排除渠道】，则“不应用”这个【附件配置】
                        || !Lists.newArrayList(item.getExcludeChannelIds().split(",")).contains(channelId)
        ).collect(Collectors.toList());

        log.debug("筛选后的【照片/视频】附件配置：{}", attachmentConfigFilterList);
        return attachmentConfigFilterList;
    }


    @Override
    public List<ConfOrderAttachmentVO> listPageByQuery(ConfOrderAttachmentQuery query) {
        if (StringUtils.isNotBlank(query.getKeyWord())) {
            if (NumberUtils.isDigits(query.getKeyWord())) {
                query.setId(Integer.valueOf(query.getKeyWord()));
            } else {
                query.setLikeAttachmentName(query.getKeyWord());
            }
        }
        query.setOrderField("sort");
        query.setDefaultOrder(1);
        List<ConfOrderAttachment> confList = confOrderAttachmentService.listPageByQuery(query);
        // 获取所有分类
        List<ConfOrderAttachmentCategory> confOrderAttachmentCategories = confOrderAttachmentCategoryService.listByQuery(new ConfOrderAttachmentCategoryQuery());
        Map<Integer, ConfOrderAttachmentCategory> confOrderAttachmentCategoriesMap = confOrderAttachmentCategories.stream().collect(Collectors.toMap(ConfOrderAttachmentCategory::getCategId, (e -> e)));
        List<ConfOrderAttachmentVO> voList = Lists.newArrayListWithExpectedSize(confList.size());

        Set<String> channelIdSet = Sets.newHashSet();
        Set<String> excludeChannelIdSet = Sets.newHashSet();
        Set<String> bizLineIdSet = Sets.newHashSet();
        Set<String> servCategIdSet = Sets.newHashSet();
        for (ConfOrderAttachment conf : confList) {
            if (StringUtils.isNotBlank(conf.getChannelIds())) {
                channelIdSet.addAll(Arrays.asList(conf.getChannelIds().split(",")));
            }
            if (StringUtils.isNotBlank(conf.getExcludeChannelIds())) {
                excludeChannelIdSet.addAll(Arrays.asList(conf.getExcludeChannelIds().split(",")));
            }
            if (StringUtils.isNotBlank(conf.getBizLineIds())) {
                bizLineIdSet.addAll(Arrays.asList(conf.getBizLineIds().split(",")));
            }
            if (StringUtils.isNotBlank(conf.getServCategIds())) {
                servCategIdSet.addAll(Arrays.asList(conf.getServCategIds().split(",")));
            }
        }

        // 渠道名称缓存
        Map<String, String> channelDROMap = processChannel(channelIdSet);
        // 排除渠道名称缓存
        Map<String, String> excludeChannelDROMap = processChannel(excludeChannelIdSet);
        // 业务线名称缓存
        Map<String, String> productBusinessLineNameAndBizTypeDROMap = processBizLine(bizLineIdSet);
        // 服务分类缓存
        Map<String, String> servCategoryDROMap = processServCateg(servCategIdSet);

        for (ConfOrderAttachment conf : confList) {
            ConfOrderAttachmentVO confOrderAttachmentVO = BeanMapper.map(conf, ConfOrderAttachmentVO.class);
            // 处理审核标准设置
            confOrderAttachmentVO.setAuditStandardStatusName(Objects.equals(conf.getAuditStandardStatus(), GlobalConsts.YES) ? "已设置" : "未设置");
            confOrderAttachmentVO.setBizTypeName(OrderConsts.getOrderBizType(conf.getBizType()));
            if (confOrderAttachmentCategoriesMap.get(conf.getCategId()) != null) {
                confOrderAttachmentVO.setCategName(confOrderAttachmentCategoriesMap.get(conf.getCategId()).getCategName());
            }
            // 处理渠道名称
            if (StringUtils.isNotBlank(conf.getChannelIds())) {
                String channelNames = Lists.newArrayList(conf.getChannelIds().split(","))
                        .stream()
                        .map(channelDROMap::get)
                        .collect(Collectors.joining(","));
                confOrderAttachmentVO.setChannelNames(channelNames);
            }

            // 处理排除渠道名称
            if (StringUtils.isNotBlank(conf.getExcludeChannelIds())) {
                String excludeChannelNames = Lists.newArrayList(conf.getExcludeChannelIds().split(","))
                        .stream()
                        .map(excludeChannelDROMap::get)
                        .collect(Collectors.joining(","));
                confOrderAttachmentVO.setExcludeChannelNames(excludeChannelNames);
            }

            // 处理业务线名称
            if (StringUtils.isNotBlank(conf.getBizLineIds())) {
                List<String> bizLIneIdList = Lists.newArrayList(conf.getBizLineIds().split(","));
                List<String> bizLIneNames = bizLIneIdList.stream().map(productBusinessLineNameAndBizTypeDROMap::get).collect(Collectors.toList());
                confOrderAttachmentVO.setBizLineNames(StringUtils.join(bizLIneNames, ","));
            }

            // 处理服务分类名称
            if (StringUtils.isNotBlank(conf.getServCategIds())) {
                List<String> servCategList = Lists.newArrayList(conf.getServCategIds().split(","));
                List<String> servCategNames = servCategList.stream().map(servCategoryDROMap::get).collect(Collectors.toList());
                confOrderAttachmentVO.setServCategNames(StringUtils.join(servCategNames, ","));
            }
            voList.add(confOrderAttachmentVO);
        }
        return voList;
    }

    @Override
    public List<ConfOrderAttachmentVO> listPicturePageByQuery(ConfOrderAttachmentQuery query) {
        String channelIdsQuery = query.getChannelIds();
        if (StringUtils.isNotBlank(channelIdsQuery)){
            List<Integer> channelIds = Arrays.asList(channelIdsQuery.split(",")).stream().map(channelId -> Integer.parseInt(channelId)).collect(Collectors.toList());
            List<Integer> useChannelAttachmentIds = confOrderAttachmentChannelService.listBatchByChannelIds(channelIds, ConfOrderAttachmentChannelTypeConsts.TYPE_USE).stream().map(ConfOrderAttachmentChannel::getAttachmentId)
                    .distinct().collect(Collectors.toList());
            List<Integer> excludeChannelAttachmentIds = confOrderAttachmentChannelService.listByQuery(ConfOrderAttachmentChannelQuery.builder().excludeType(ConfOrderAttachmentChannelTypeConsts.TYPE_EXCLUDE).build())
                    // 查出全部排除的渠道
                    .stream().filter(channel -> {
                        if (channelIds.contains(channel.getChannelId())) {
                            return false;
                        }
                        return true;
                    }).distinct().map(ConfOrderAttachmentChannel::getAttachmentId).collect(Collectors.toList());
            useChannelAttachmentIds.addAll(excludeChannelAttachmentIds);
            query.setChannelAttachmentIds(useChannelAttachmentIds);
        }
        String servCategIdsQuery = query.getServCategIds();
        List<Integer> servCategAttachmentIds = new ArrayList<>();
        if (StringUtils.isNotBlank(servCategIdsQuery)){
            List<Integer> servCategIds = Arrays.asList(servCategIdsQuery.split(",")).stream().map(servCategId -> Integer.parseInt(servCategId)).collect(Collectors.toList());
            servCategAttachmentIds = confOrderAttachmentProductService.listBatchByServCategIds(servCategIds).stream().map(ConfOrderAttachmentProduct::getAttachmentId)
                    .distinct().collect(Collectors.toList());
            query.setProductAttachmentIds(servCategAttachmentIds);
        }



        if (StringUtils.isNotBlank(query.getKeyWord())) {
            if (NumberUtils.isDigits(query.getKeyWord())) {
                query.setId(Integer.valueOf(query.getKeyWord()));
            } else {
                query.setLikeAttachmentName(query.getKeyWord());
            }
        }
        query.setOrderField("sort");
        query.setDefaultOrder(1);
        List<ConfOrderAttachment> confList = confOrderAttachmentService.listPicturePageByQuery(query);
        // 获取所有分类
        List<ConfOrderAttachmentCategory> confOrderAttachmentCategories = confOrderAttachmentCategoryService.listByQuery(new ConfOrderAttachmentCategoryQuery());
        Map<Integer, ConfOrderAttachmentCategory> confOrderAttachmentCategoriesMap = confOrderAttachmentCategories.stream().collect(Collectors.toMap(ConfOrderAttachmentCategory::getCategId, (e -> e)));
        List<ConfOrderAttachmentVO> voList = Lists.newArrayListWithExpectedSize(confList.size());



        // 所有配置id
        List<Integer> dbAttachmentIds = confList.stream().map(ConfOrderAttachment::getId).collect(Collectors.toList());

        Map<Integer, List<ConfOrderAttachmentChannel>> confOrderAttachmentChannelMap = new HashMap<>();
        Map<Integer, List<ConfOrderAttachmentProduct>> servCategoryMap = new HashMap<>();
        if (CollectionUtil.isNotNullOrEmpty(dbAttachmentIds)){
            List<ConfOrderAttachmentChannel> confOrderAttachmentChannels = confOrderAttachmentChannelService.listBatch(dbAttachmentIds);
            if (CollectionUtil.isNotNullOrEmpty(confOrderAttachmentChannels)){
                // 查询渠道
                confOrderAttachmentChannelMap = confOrderAttachmentChannels.stream().collect(Collectors.groupingBy(ConfOrderAttachmentChannel::getAttachmentId));
            }
            // 查询服务id
            List<ConfOrderAttachmentProduct> confOrderAttachmentProducts = confOrderAttachmentProductService.listBatch(dbAttachmentIds);
            if (CollectionUtil.isNotNullOrEmpty(confOrderAttachmentProducts)){
                servCategoryMap = confOrderAttachmentProducts.stream().collect(Collectors.groupingBy(ConfOrderAttachmentProduct::getAttachmentId));
            }
        }



        // 服务分类缓存
        Map<Integer, String> servCategoryDROMap = processPictureServCateg();

        for (ConfOrderAttachment conf : confList) {
            ConfOrderAttachmentVO confOrderAttachmentVO = BeanMapper.map(conf, ConfOrderAttachmentVO.class);
            // 处理审核标准设置
            confOrderAttachmentVO.setAuditStandardStatusName(Objects.equals(conf.getAuditStandardStatus(), GlobalConsts.YES) ? "已设置" : "未设置");
            confOrderAttachmentVO.setBizTypeName(OrderConsts.getOrderBizType(conf.getBizType()));
            if (confOrderAttachmentCategoriesMap.get(conf.getCategId()) != null) {
                confOrderAttachmentVO.setCategName(confOrderAttachmentCategoriesMap.get(conf.getCategId()).getCategName());
            }
            // 处理渠道名称
            if (conf.getAllChannel().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_USE)){
                // 渠道类型为使用
                String channelNames = confOrderAttachmentChannelMap.get(conf.getId()).stream()
                        .filter(channel -> channel.getExcludeType().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_USE))
                        .map(ConfOrderAttachmentChannel::getChannelName)
                        .collect(Collectors.joining(","));
                confOrderAttachmentVO.setChannelNames(channelNames);
            }

            // 处理排除渠道名称
            if (conf.getAllChannel().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_EXCLUDE)){
                // 渠道类型为排除
                String channelNames = confOrderAttachmentChannelMap.get(conf.getId()).stream()
                        .filter(channel -> channel.getExcludeType().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_EXCLUDE))
                        .map(ConfOrderAttachmentChannel::getChannelName)
                        .collect(Collectors.joining(","));
                confOrderAttachmentVO.setExcludeChannelNames(channelNames);
            }

            // 处理全渠道
            if (conf.getAllChannel().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_ALL)){
                confOrderAttachmentVO.setChannelNames("全渠道");
            }

            // 处理服务分类名称

            if (conf.getAllProduct()){
                // 处理全服务分类的情况
                confOrderAttachmentVO.setServCategNames(StringUtils.join(servCategoryDROMap.values(), ","));
            }else {
                List<ConfOrderAttachmentProduct> confOrderAttachmentProducts = servCategoryMap.get(conf.getId());
                List<Integer> servCategList = new ArrayList<>();
                if (CollectionUtil.isNotNullOrEmpty(confOrderAttachmentProducts)){
                    servCategList = confOrderAttachmentProducts.stream().map(ConfOrderAttachmentProduct::getServCategId).distinct().collect(Collectors.toList());
                }
                if (CollectionUtil.isNotNullOrEmpty(servCategList)) {
                    List<String> servCategNames = servCategList.stream().map(servCategoryDROMap::get).collect(Collectors.toList());
                    confOrderAttachmentVO.setServCategNames(StringUtils.join(servCategNames, ","));
                }
            }

            voList.add(confOrderAttachmentVO);
        }
        return voList;
    }

    @Override
    public Collection<ServerClassDataBO> listAllServerClass() {
        ProductBaseQuery productBaseQuery = new ProductBaseQuery();
        productBaseQuery.setStatus(com.zmn.common.constant.GlobalConsts.YES);
        productBaseQuery.setShowType(BaseProductConsts.EC_SHOW_TYPE);
        ResponseDTO<List<com.zmn.base.product.common.dto.product.ec.ProductBaseDRO>> productListResponseDTO =
                productForeignListRemoteService.listBaseDROByQuery(productBaseQuery);
        if (!productListResponseDTO.isSuccess() || org.springframework.util.CollectionUtils.isEmpty(productListResponseDTO.getData())) {
            log.error("{},未查询到产品信息<productForeignListRemoteService.listBaseDROByQuery>,message:{}", TAG, productListResponseDTO.getMessage());
            return null;
        }

        List<ServerClassDataBO> allServerClass = new ArrayList<>();
        if (!productListResponseDTO.isSuccess()) {
            return allServerClass;
        }

        List<ProductBaseDRO> servProductDROS = productListResponseDTO.getData();

        //服务组
        Map<Integer, List<ProductBaseDRO>> serverGroup = servProductDROS.stream().collect(Collectors.groupingBy(o -> o.getServCategId()));

        //一级分类组
        Map<String, List<ProductBaseDRO>> oneGroup = servProductDROS.stream().collect(Collectors.groupingBy(o -> o.getServCategId() + "_" + o.getCategOneId()));

        //二级分类组
        Map<String, List<ProductBaseDRO>> twoGroup = servProductDROS.stream().collect(Collectors.groupingBy(o -> o.getServCategId() + "_" + o.getCategOneId() + "_" + o.getCategId()));

        //产品组
        Map<String, List<ProductBaseDRO>> productGroup = servProductDROS.stream().collect(Collectors.groupingBy(o -> o.getServCategId() + "_" + o.getCategOneId() + "_" + o.getCategId() + "_" + o.getProductId()));

        //构造树形菜单
        serverGroup.forEach((sk, sv) -> {
            ProductBaseDRO servProduct = sv.get(0);
            log.debug("{},产品分类信息:{}", TAG, servProduct);
            ServerClassDataBO promServerClassDRO = new ServerClassDataBO(sk, servProduct.getServCategName(), Integer.valueOf("0"), String.valueOf(sk), "服务分类");
            promServerClassDRO.setSort(servProduct.getSort());
            oneGroup.forEach((ok, ov) -> {
                ProductBaseDRO oneProduct = ov.get(0);
                if (sk.equals(oneProduct.getServCategId())) {
                    ServerClassDataBO promOneClassDRO = new ServerClassDataBO(oneProduct.getCategOneId(), oneProduct.getCategOneName(), sk, String.valueOf(sk), "一级分类");
                    twoGroup.forEach((tk, tv) -> {
                        ProductBaseDRO twoProduct = tv.get(0);
                        if (ok.equals(twoProduct.getServCategId() + "_" + twoProduct.getCategOneId())) {
                            ServerClassDataBO promTwoClassDRO = new ServerClassDataBO(twoProduct.getCategId(), twoProduct.getCategName(), oneProduct.getCategOneId()
                                    , ok, "二级分类");
                            productGroup.forEach((pk, pv) -> {
                                ProductBaseDRO product = pv.get(0);
                                if (tk.equals(product.getServCategId() + "_" + product.getCategOneId() + "_" + product.getCategId())) {
                                    ServerClassDataBO productDRO = new ServerClassDataBO(product.getProductId(), product.getProductName(), product.getCategId()
                                            , tk, "产品");
                                    promTwoClassDRO.addProduct(productDRO);
                                }
                            });
                            promOneClassDRO.addChildren(promTwoClassDRO);
                        }
                    });
                    promServerClassDRO.addChildren(promOneClassDRO);
                }
            });
            allServerClass.add(promServerClassDRO);
        });

        return allServerClass.stream().sorted(Comparator.comparing(ServerClassDataBO::getSort)).collect(Collectors.toList());
    }

    @Override
    public ResponseDTO<AMISListData<ChannelDRO>> listChannel(ConfOrderChannelQuery query) {
        ChannelQuery channelQuery = BeanUtil.copyProperties(query, ChannelQuery.class);
        return channelListRemoteService.listPageByQuery(channelQuery);
    }


    /**
     * 查询指定【附件类型】的配置
     *
     * @param orderAttachmentQuery
     * @return 对应附件类型的配置
     * @author liudi
     * @since: 2022/4/21 12:02
     */
    @Override
    public ConfOrderAttachment getAttachmentConfigByQuery(OrderAttachmentQuery orderAttachmentQuery) {
        Objects.requireNonNull(orderAttachmentQuery.getType());

        List<ConfOrderAttachment> configList;

        // 获取照片配置
        log.debug("工单号：[{}]，查询【类型为：[{}] 的配置】", orderAttachmentQuery.getOrderId(), orderAttachmentQuery.getType());
        if (OrderAttachmentConsts.isVideoType(orderAttachmentQuery.getType())) {
            configList = this.listConfigOrderVideoAttachmentByQuery(orderAttachmentQuery);
        } else {
            configList = this.listConfigOrderPictureAttachmentByQuery(orderAttachmentQuery);
        }

        if (CollectionUtils.isEmpty(configList)) {
            return null;
        }

        return configList.get(0);
    }

    @Override
    public ConfOrderAttachmentPictureVO getAttachmentConfigPictureDetail(Integer id) {
        ConfOrderAttachmentPictureVO vo = new ConfOrderAttachmentPictureVO();
        // 查询基本信息
        ConfOrderAttachment confOrderAttachment = confOrderAttachmentService.findById(id);
        vo.setConfOrderAttachment(confOrderAttachment);

        // 查询渠道
        List<ConfOrderAttachmentChannel> channels = confOrderAttachmentChannelService.listByQuery(ConfOrderAttachmentChannelQuery.builder().attachmentId(id).build());
        List<ConfOrderAttachmentChannelDRO> confOrderAttachmentChannelDROS = BeanUtil.copyToList(channels, ConfOrderAttachmentChannelDRO.class);
        vo.setConfOrderAttachmentChannelDROS(confOrderAttachmentChannelDROS);

        // 查询城市id
        List<ConfOrderAttachmentCity> cities = confOrderAttachmentCityService.listByQuery(ConfOrderAttachmentCityQuery.builder().attachmentId(id).build());
        List<ConfOrderAttachmentCityDRO> confOrderAttachmentCityDROS = BeanUtil.copyToList(cities, ConfOrderAttachmentCityDRO.class);
        vo.setSelectedCities(confOrderAttachmentCityDROS);

        // 查询产品
        List<ConfOrderAttachmentProduct> products = confOrderAttachmentProductService.listByQuery(ConfOrderAttachmentProductQuery.builder().attachmentId(id).build());
        List<Integer> productIds = products.stream().map(ConfOrderAttachmentProduct::getProductId).collect(Collectors.toList());
        List<Integer> servCategIds = products.stream().map(ConfOrderAttachmentProduct::getServCategId).collect(Collectors.toList());
        List<Integer> categOneIds = products.stream().map(ConfOrderAttachmentProduct::getCategOneId).collect(Collectors.toList());
        List<Integer> categIds = products.stream().map(ConfOrderAttachmentProduct::getCategTwoId).collect(Collectors.toList());
        vo.setProductIds(productIds);
        vo.setServCategIds(servCategIds);
        vo.setCategOneIds(categOneIds);
        vo.setCategIds(categIds);
        return vo;
    }

    /**
     * 查询渠道名称信息
     *
     * @param channelIdSet
     * @return
     */
    private Map<String, String> processChannel(Set<String> channelIdSet) {
        Map<String, String> channelMap = Maps.newHashMap();
        if (CollectionUtil.isNullOrEmpty(channelIdSet)) {
            return channelMap;
        }
        List<Integer> ids = channelIdSet.stream().map(e -> Integer.valueOf(e)).collect(Collectors.toList());
        ResponseDTO<List<ChannelDRO>> listResponseDTO = channelListRemoteService.listByChannelIds(ids);
        if (!listResponseDTO.isSuccess() || Objects.isNull(listResponseDTO.getData())) {
            return channelMap;

        }
        return listResponseDTO.getData().stream().collect(Collectors.toMap(e -> String.valueOf(e.getChannelId()), (e -> StringUtils.defaultString(e.getName())), (a, e) -> e));
    }

    /**
     * 查询业务线信息
     *
     * @param bizLineIdSet
     * @return
     */
    private Map<String, String> processBizLine(Set<String> bizLineIdSet) {
        Map<String, String> channelMap = Maps.newHashMap();
        if (Objects.isNull(bizLineIdSet)) {
            return channelMap;
        }
        List<Integer> ids = bizLineIdSet.stream().map(e -> Integer.valueOf(e)).collect(Collectors.toList());
        ProductBusinessLineQuery build = ProductBusinessLineQuery
                .builder()
                .ids(ids)
                .build();
        ResponseDTO<List<ProductBusinessLineDRO>> listResponseDTO = productBusinessLineForeignListRemoteService.listDROByQuery(build);
        if (!listResponseDTO.isSuccess() || Objects.isNull(listResponseDTO.getData())) {
            return channelMap;

        }
        return listResponseDTO.getData().stream().collect(Collectors.toMap(e -> String.valueOf(e.getRelateId()), (e -> StringUtils.defaultString(e.getName())), (a, e) -> e));
    }

    /**
     * 查询服务分类
     *
     * @param servCategIdSet
     * @return
     */
    private Map<String, String> processServCateg(Set<String> servCategIdSet) {
        Map<String, String> servCategoryMap = Maps.newHashMap();
        if (CollectionUtil.isNullOrEmpty(servCategIdSet)) {
            return servCategoryMap;
        }
        ResponseDTO<List<CategServDRO>> listResponseDTO = categServListRemoteService.listByQuery(new ForeignCategServQuery());

        if (!listResponseDTO.isSuccess() || Objects.isNull(listResponseDTO.getData())) {
            return servCategoryMap;
        }
        return listResponseDTO.getData().stream().collect(Collectors.toMap(e -> String.valueOf(e.getServCategId()), (e -> StringUtils.defaultString(e.getServCategName())), (a, e) -> e));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyConfById(ConfOrderAttachment conf) throws OmsBaseException {
        Objects.requireNonNull(conf.getId(), "ID不能为空");

        // 判断是否有重复的附件配置
        this.hasConfOrderAttachmentsDuplicate(conf);

        ConfOrderAttachment updateConf = ConfOrderAttachment.builder()
                .id(conf.getId())
                .categId(conf.getCategId())
                .sort(conf.getSort())
                .num(conf.getNum())
                .sort(conf.getSort())
                .channelIds(conf.getChannelIds())
                .excludeChannelIds(conf.getExcludeChannelIds())
                .bizType(conf.getBizType())
                .servCategIds(conf.getServCategIds())
                .bizLineIds(conf.getBizLineIds())
                .needReview(conf.getNeedReview())
                .mustUpload(conf.getMustUpload())
                .autoAudit(conf.getAutoAudit())
                .egSrc(conf.getEgSrc())
                .description(conf.getDescription())
                .detailDescription(conf.getDetailDescription())
                .creater(conf.getCreater())
                .updater(conf.getUpdater())
                .createTime(conf.getCreateTime())
                .updateTime(conf.getUpdateTime()).build();
        confOrderAttachmentService.updateConfById(updateConf);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyConfPictureById(ConfOrderAttachmentDIO dio) throws OmsBaseException {
        // 校验是否照片配置是否相同
        checkPictureConf(dio);
        // 修改照片配置
        ConfOrderAttachment confOrderAttachment = BeanUtil.copyProperties(dio, ConfOrderAttachment.class);
        confOrderAttachmentService.updateConfById(confOrderAttachment);
        // 修改渠道
        confOrderAttachmentChannelService.deleteByAttachmentId(dio.getId());
        if (!Objects.equals(dio.getAllChannel(), ConfOrderAttachmentChannelTypeConsts.TYPE_ALL)) {
            // 渠道的新增
            addAttachmentChannel(dio);
        }

        // 修改城市
        confOrderAttachmentCityService.deleteByAttachmentId(dio.getId());
        if (!dio.getAllCity()){
            // 城市的新增
            addAttachmentCity(dio);
        }

        // 修改产品
        confOrderAttachmentProductService.deleteByAttachmentId(dio.getId());
        if (!dio.getAllProduct()){
            // 产品的新增
            addAttachmentProduct(dio);
        }
    }

    /**
     * 是否有重复的附件配置
     *
     * @param confOrderAttachment
     * @return
     * @author liudi
     */
    private void hasConfOrderAttachmentsDuplicate(ConfOrderAttachment confOrderAttachment) throws OmsBaseException {
        ConfOrderAttachmentQuery confOrderAttachmentQuery = new ConfOrderAttachmentQuery();
        confOrderAttachmentQuery.setCategId(confOrderAttachment.getCategId());
        confOrderAttachmentQuery.setBizType(confOrderAttachment.getBizType());

        log.debug("ConfOrderAttachmentBService#has...Duplicate【listByQuery】 入参： {}", confOrderAttachmentQuery);
        List<ConfOrderAttachment> confOrderAttachments = confOrderAttachmentService.listByQuery(confOrderAttachmentQuery);
        log.debug("ConfOrderAttachmentBService#has...Duplicate【listByQuery】 出参： {}", confOrderAttachments);

        // 没有重复的数据
        if (CollectionUtils.isEmpty(confOrderAttachments)) {
            return;
        }

        Stream<Integer> duplicateStream = confOrderAttachments.stream().map(ConfOrderAttachment::getId);
        if (Objects.nonNull(confOrderAttachment.getId())) {

            // 没有重复数据
            if (Objects.equals(confOrderAttachment.getId(), confOrderAttachments.get(0).getId())) {
                return;
            }
            // 获取非【前台】传递过来的id
            duplicateStream = duplicateStream.filter(confId -> !Objects.equals(confOrderAttachment.getId(), confId));
        }

        String duplicateIds = duplicateStream
                .map(String::valueOf)
                .collect(Collectors.joining(","));

        // 如果继续往下执行 说明有重复的内容，因为新增操作数据库中不会有相同的数据，而编辑至少有一个数据，但走说明一定有重复。
        throw new OmsBaseException(String.format("相同的配置已存在，请重新选择。相同的【照片配置】ID：[%s]。", duplicateIds));
    }

    @Override
    @Transactional
    public void modifyConfReviewById(ConfOrderAttachment conf) {
        Objects.requireNonNull(conf.getId(), "ID不能为空");
        ConfOrderAttachment updateConf = ConfOrderAttachment.builder()
                .id(conf.getId())
                .needReview(conf.getNeedReview())
                .updater(conf.getUpdater()).build();
        confOrderAttachmentService.updateConfById(updateConf);
    }

    @Override
    @Transactional
    public void modifyConfSortById(ConfOrderAttachment conf) {
        Objects.requireNonNull(conf.getId(), "ID不能为空");

        ConfOrderAttachment updateConf = ConfOrderAttachment.builder()
                .id(conf.getId())
                .sort(conf.getSort())
                .updater(conf.getUpdater()).build();
        confOrderAttachmentService.updateConfById(updateConf);
    }

    @Override
    @Transactional
    public void modifyConfMustUploadById(ConfOrderAttachment conf) {
        Objects.requireNonNull(conf.getId(), "ID不能为空");
        ConfOrderAttachment updateConf = ConfOrderAttachment.builder()
                .id(conf.getId())
                .mustUpload(conf.getMustUpload())
                .updater(conf.getUpdater()).build();
        confOrderAttachmentService.updateConfById(updateConf);
    }

    @Override
    @Transactional
    public void modifyConfAutoAuditById(ConfOrderAttachment conf) {
        Objects.requireNonNull(conf.getId(), "ID不能为空");
        ConfOrderAttachment updateConf = ConfOrderAttachment.builder()
                .id(conf.getId())
                .autoAudit(conf.getAutoAudit())
                .updater(conf.getUpdater()).build();
        confOrderAttachmentService.updateConfById(updateConf);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addConf(ConfOrderAttachment conf) throws OmsBaseException {
        // 判断是否有重复的附件配置
        this.hasConfOrderAttachmentsDuplicate(conf);

        return confOrderAttachmentService.insertConf(conf);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addConfPicture(ConfOrderAttachmentDIO dio) throws OmsBaseException {
        // 检验照片配置是否相同
        checkPictureConf(dio);

        // 新增照片配置
        ConfOrderAttachment conf = BeanUtil.copyProperties(dio, ConfOrderAttachment.class);
        confOrderAttachmentService.insertConf(conf);
        dio.setId(conf.getId());

        if (!(dio.getAllChannel().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_ALL))){
            // 渠道的新增
            addAttachmentChannel(dio);
        }
        if (!dio.getAllCity()){
            // 城市的新增
            addAttachmentCity(dio);
        }
        if (!dio.getAllProduct()){
            // 产品的新增
            addAttachmentProduct(dio);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByAttachmentId(Integer id) {
        // 删除基本信息
        confOrderAttachmentService.deleteById(id);

        // 删除附件审核标准配置表
        confOrderAttachmentStandardService.deleteByAttachmentId(id);

        // 删除渠道
        confOrderAttachmentChannelService.deleteByAttachmentId(id);

        // 删除城市
        confOrderAttachmentCityService.deleteByAttachmentId(id);

        // 删除产品
        confOrderAttachmentProductService.deleteByAttachmentId(id);

    }


    /**
     * 校验是否有相同的照片配置
     * 相同照片类型信息，城市、渠道、产品不能有交集
     *
     * @param dio
     */
    private void checkPictureConf(ConfOrderAttachmentDIO dio) throws OmsBaseException {
        log.debug("检验相同照片配置入参:{}",dio);
        List<ConfOrderAttachment> confOrderAttachments = confOrderAttachmentService.listByQuery(ConfOrderAttachmentQuery.builder().categId(dio.getCategId()).bizType(dio.getBizType()).build());
        // 如果本次是修改操作 不与本身数据进行比较
        if (Objects.nonNull(dio.getId())){
            confOrderAttachments = confOrderAttachments.stream().filter(confOrderAttachment -> !Objects.equals(dio.getId(), confOrderAttachment.getId())).collect(Collectors.toList());
        }
        if(CollectionUtil.isNullOrEmpty(confOrderAttachments)){
            return;
        }
        Boolean sameChannel = false;
        Boolean sameCity = false;
        Boolean sameProduct = false;
        for (ConfOrderAttachment confOrderAttachment : confOrderAttachments) {
            if (confOrderAttachment.getAllChannel().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_ALL) && !sameChannel){
                // 说明数据库内有相同渠道
                sameChannel = true;
            }
            if (confOrderAttachment.getAllCity() && !sameCity){
                // 说明数据库内有相同城市
                sameCity = true;
            }
            if (confOrderAttachment.getAllProduct() && !sameProduct){
                // 说明数据库内有相同产品
                sameProduct = true;
            }

        }

        List<Integer> confOrderAttachmentIds = confOrderAttachments.stream().map(ConfOrderAttachment::getId).collect(Collectors.toList());

        // 若是所有渠道 不需要查询
        if (!sameChannel){
            sameChannel = checkSameChannel(dio, confOrderAttachmentIds);
        }

        // 城市
        if(!sameCity){
            sameCity = checkSameCity(dio, confOrderAttachmentIds);
        }

        // 产品
        if (!sameProduct){
            sameProduct = checkSameProduct(dio, confOrderAttachmentIds);
        }

        if (sameChannel && sameCity && sameProduct) {
            throw new OmsBaseException("与已有相同照片类型+业务类型配置的：城市、渠道、产品信息重复，请确认后再保存。");
        }
        log.info("相同渠道:{},相同城市:{},相同产品:{}",sameChannel,sameCity,sameProduct);
    }

    /**
     * 检验是否为相同渠道
     * @param dio
     * @param confOrderAttachmentIds
     * @return
     */
    private Boolean checkSameChannel(ConfOrderAttachmentDIO dio, List<Integer> confOrderAttachmentIds) {
        Boolean sameChannel = dio.getAllChannel().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_ALL);
        if (!sameChannel){
            // 查出对应照片配置的渠道
            List<ConfOrderAttachmentChannel> confOrderAttachmentChannels = confOrderAttachmentChannelService.listBatch(confOrderAttachmentIds);
            log.debug("[{}]:查询渠道表,入参:confOrderAttachmentIds:{},出参:confOrderAttachmentChannels:{}",TAG,confOrderAttachmentIds,confOrderAttachmentChannels);
            if (CollectionUtil.isNotNullOrEmpty(confOrderAttachmentChannels)){
                // 传入的attachmentChannelIds
                List<Integer> attachmentChannelIds = dio.getConfOrderAttachmentChannelDIOS().stream().map(ConfOrderAttachmentChannelDIO::getChannelId).collect(Collectors.toList());
                log.debug("[{}]:传入的attachmentChannelIds:{}",TAG,attachmentChannelIds);
                // 查出使用的channelId
                List<Integer> useChannelIds = confOrderAttachmentChannels.stream().filter(channel -> {
                    return channel.getExcludeType().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_USE);
                }).map(ConfOrderAttachmentChannel::getChannelId).distinct().collect(Collectors.toList());
                // 查出排除的channelId
                List<Integer> excludeChannelIds = confOrderAttachmentChannels.stream().filter(channel -> {
                    return channel.getExcludeType().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_EXCLUDE);
                }).map(ConfOrderAttachmentChannel::getChannelId).distinct().collect(Collectors.toList());
                log.debug("[{}]:使用的channelId:{},排除的channelId:{}",TAG,useChannelIds,excludeChannelIds);
                if (dio.getAllChannel().equals(ConfOrderAttachmentChannelTypeConsts.TYPE_USE)){
                    // 这次新增的渠道类型为使用 数据库里面的渠道类型是使用  则不等于传入的
                    for (Integer useChannelId : useChannelIds) {
                        if (attachmentChannelIds.contains(useChannelId)) {
                            sameChannel = true;
                            log.info("[{}]:数据库内渠道类型为使用,存在相同渠道:{},传入渠道Id为:{}",TAG,useChannelId,attachmentChannelIds);
                            break;
                        }
                    }

                    if (!sameChannel && CollectionUtil.isNotNullOrEmpty(excludeChannelIds)){
                        // 数据库内是排除的 则必须等于传入的
                        for (Integer attachmentChannelId : attachmentChannelIds) {
                            if (!excludeChannelIds.contains(attachmentChannelId)){
                                sameChannel=true;
                                log.info("[{}]:数据库内渠道类型为排除,存在相同渠道:{}",TAG,attachmentChannelId);
                                break;
                            }
                        }

                    }
                }else{
                    // 如果数据库内有同是排除的数据 这次新增无效
                    if (CollectionUtil.isNotNullOrEmpty(excludeChannelIds)){
                        log.info("[{}]:此次新增是排除数据，数据库内有排除数据，新增无效",TAG);
                        sameChannel = true;
                    }
                    if (!sameChannel){
                        // 这次新增的渠道类型为排除 数据库里面的渠道类型是使用  则必须等于传入的
                        for (Integer useChannelId : useChannelIds) {
                            if (!attachmentChannelIds.contains(useChannelId)) {
                                log.info("[{}]:此次新增是排除数据，数据库内有使用数据,渠道id为:{}",TAG,useChannelId);
                                sameChannel = true;
                                break;
                            }
                        }
                    }

                }
            }

        }
        return sameChannel;
    }

    /**
     * 检验是否有相同产品
     * @param dio
     * @param confOrderAttachmentIds
     * @return
     */
    private Boolean checkSameProduct(ConfOrderAttachmentDIO dio, List<Integer> confOrderAttachmentIds) {
        Boolean sameProduct = dio.getAllProduct();
        if (!sameProduct){
            // 查出对应照片配置的城市
            List<ConfOrderAttachmentProduct> confOrderAttachmentProducts = confOrderAttachmentProductService.listBatch(confOrderAttachmentIds);
            log.debug("[{}]:查出对应照片配置的产品,入参,confOrderAttachmentIds:{},出参,confOrderAttachmentProducts:{}",TAG,confOrderAttachmentIds,confOrderAttachmentProducts);
            if (CollectionUtil.isNotNullOrEmpty(confOrderAttachmentProducts)){
                List<Integer> attachmentProductIds = confOrderAttachmentProducts.stream().map(ConfOrderAttachmentProduct::getProductId).collect(Collectors.toList());
                List<Integer> productIds = dio.getProductIds();
                for (Integer productId : productIds) {
                    if (attachmentProductIds.contains(productId)) {
                        log.info("[{}]:查询到相同产品，产品Id为:{}",TAG,productId);
                        sameProduct = true;
                        break;
                    }
                }
            }
        }
        return sameProduct;
    }

    /**
     * 检验是否有相同城市
     * @param dio
     * @param confOrderAttachmentIds
     * @return
     */
    private Boolean checkSameCity(ConfOrderAttachmentDIO dio, List<Integer> confOrderAttachmentIds) {
        Boolean sameCity = dio.getAllCity();
        if (!sameCity){
            // 查出对应照片配置的城市
            List<ConfOrderAttachmentCity> confOrderAttachmentCities = confOrderAttachmentCityService.listBatch(confOrderAttachmentIds);
            log.debug("[{}]:查出对应照片配置的城市,入参,confOrderAttachmentIds:{},出参,confOrderAttachmentCities:{}",TAG,confOrderAttachmentIds,confOrderAttachmentCities);
            if (CollectionUtil.isNotNullOrEmpty(confOrderAttachmentCities)){
                List<Integer> attachmentCityIds = confOrderAttachmentCities.stream().map(ConfOrderAttachmentCity::getCityId).collect(Collectors.toList());
                List<Integer> cityIds = dio.getConfOrderAttachmentCities().stream().map(ConfOrderAttachmentCity::getCityId).collect(Collectors.toList());
                for (Integer cityId : cityIds) {
                    if (attachmentCityIds.contains(cityId)) {
                        log.info("[{}]:查询到相同城市，城市Id为:{}",TAG,cityId);
                        sameCity = true;
                        break;
                    }
                }
            }
        }
        return sameCity;
    }

    /**
     * 渠道的新增
     *
     * @param dio
     */
    private void addAttachmentChannel(ConfOrderAttachmentDIO dio) {
        if(CollectionUtil.isNotNullOrEmpty(dio.getConfOrderAttachmentChannelDIOS())){
            List<ConfOrderAttachmentChannelDIO> confOrderAttachmentChannelDIOS = dio.getConfOrderAttachmentChannelDIOS();
            List confOrderAttachmentChannels = new ArrayList<ConfOrderAttachmentChannel>();
            confOrderAttachmentChannelDIOS.stream().forEach(confOrderAttachmentChannel -> {
                ConfOrderAttachmentChannel channel = new ConfOrderAttachmentChannel();
                channel.setAttachmentId(dio.getId());
                channel.setCreater(dio.getCreater());
                channel.setExcludeType(dio.getAllChannel());
                channel.setChannelId(confOrderAttachmentChannel.getChannelId());
                channel.setChannelName(confOrderAttachmentChannel.getChannelName());
                confOrderAttachmentChannels.add(channel);
            });
            confOrderAttachmentChannelService.insertBatch(confOrderAttachmentChannels);
        }
    }

    /**
     * 城市的新增
     *
     * @param dio
     */
    private void addAttachmentCity(ConfOrderAttachmentDIO dio) {
        if (CollectionUtil.isNotNullOrEmpty(dio.getConfOrderAttachmentCities())){
            List<ConfOrderAttachmentCity> confOrderAttachmentCities = dio.getConfOrderAttachmentCities();
            confOrderAttachmentCities.stream().forEach(city->{
                city.setAttachmentId(dio.getId());
                city.setCreater(dio.getCreater());
            });
            confOrderAttachmentCityService.insertBatch(confOrderAttachmentCities);
        }
    }

    /**
     * 产品的新增
     *
     * @param dio
     */
    private void addAttachmentProduct(ConfOrderAttachmentDIO dio) throws OmsBaseException {
        if (CollectionUtil.isNotNullOrEmpty(dio.getProductIds())){
            List<Integer> productIds = dio.getProductIds();
            ProductBaseQuery query = new ProductBaseQuery();
            query.setStatus(com.zmn.common.constant.GlobalConsts.YES);
            query.setBizType(BaseProductConsts.BIZ_TYPE_C);
            query.setShowType(BaseProductConsts.EC_SHOW_TYPE);
            query.setProductIdList(productIds);
            log.debug("{},接口<productForeignListRemoteService.listBaseDROByQuery>的请求参数:{}", TAG, JSONObject.toJSONString(query));
            ResponseDTO<List<ProductBaseDRO>> listResponseDTO = productForeignListRemoteService.listBaseDROByQuery(query);
            log.debug("{},接口<productForeignListRemoteService.listBaseDROByQuery>的响应:{}", TAG, JSONObject.toJSONString(listResponseDTO));
            if(!listResponseDTO.isSuccess() || CollectionUtils.isEmpty(listResponseDTO.getData())) {
                log.error("{},调用dubbo获取产品信息异常，入参：{}，出参：{}", TAG, query, JSONObject.toJSON(listResponseDTO));
                throw new OmsBaseException("调用dubbo获取产品信息异常");
            }
            List<ConfOrderAttachmentProduct> confOrderAttachmentProducts = new ArrayList<ConfOrderAttachmentProduct>(productIds.size());
            listResponseDTO.getData().stream().forEach(product->{
                ConfOrderAttachmentProduct confOrderAttachmentProduct = new ConfOrderAttachmentProduct();
                confOrderAttachmentProduct.setAttachmentId(dio.getId());
                confOrderAttachmentProduct.setProductId(product.getProductId());
                confOrderAttachmentProduct.setServCategId(product.getServCategId());
                confOrderAttachmentProduct.setCategOneId(product.getCategOneId());
                confOrderAttachmentProduct.setCategTwoId(product.getCategId());
                confOrderAttachmentProduct.setCreater(dio.getCreater());
                confOrderAttachmentProducts.add(confOrderAttachmentProduct);
            });
            confOrderAttachmentProductService.insertBatch(confOrderAttachmentProducts);
        }
    }

    /**
     * 过滤不满足条件的【照片配置】，验证【特殊业务规则】，如果不满足就移除对应配置。
     *
     * @param orderWork
     * @param confOrderAttachmentMap 附件配置数据
     * @author liudi
     * @since: 2022/3/30 11:09
     */
    private void filterPictureConfigBySpecialRules(OrderWork orderWork,
                                                   Map<Integer, ConfOrderAttachment> confOrderAttachmentMap) {
        for (Integer pictureType : OrderAttachmentTypeEnum.SPECIAL_RULE_PICTURE_LIST) {
            switch (pictureType) {
                // 装备照
                case OrderAttachmentTypeEnum.CONSTS_ZBZ:
                    this.filterEquipmentPictureConfig(orderWork, confOrderAttachmentMap);
                    break;
                default:
                    log.error("无对应【照片类型】的特殊规则。pictureType：{}", pictureType);
                    break;
            }
        }
    }

    /**
     * 验证装备照是否符合业务规则，如果不符合删除
     *
     * @param orderWork
     * @param confOrderAttachmentMap 从数据库中查询出来的附件配置数据
     * @author liudi
     * @since: 2022/3/30 11:15
     */
    private void filterEquipmentPictureConfig(OrderWork orderWork, Map<Integer, ConfOrderAttachment> confOrderAttachmentMap) {
        // 业务规则：有装备照 && 非家修匠
        ConfOrderAttachment equipmentPictureConfig = confOrderAttachmentMap.get(OrderAttachmentTypeEnum.CONSTS_ZBZ);
        if (Objects.isNull(equipmentPictureConfig)) {
            return;
        }

        if (Objects.equals(orderWork.getCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID)) {
            log.info("该订单:[{}]，不符合装备照的特殊业务规则。");
            confOrderAttachmentMap.remove(OrderAttachmentTypeEnum.CONSTS_ZBZ);
        }
    }

    /**
     * 查询服务分类
     *
     * @param
     * @return
     */
    private Map<Integer, String> processPictureServCateg() {
        Map<Integer, String> servCategoryMap = Maps.newHashMap();

        ResponseDTO<List<CategServDRO>> listResponseDTO = categServListRemoteService.listByQuery(new ForeignCategServQuery());

        if (!listResponseDTO.isSuccess() || Objects.isNull(listResponseDTO.getData())) {
            return servCategoryMap;
        }
        return listResponseDTO.getData().stream().collect(Collectors.toMap(e -> e.getServCategId(), (e -> StringUtils.defaultString(e.getServCategName())), (a, e) -> e));
    }
}
